package com.kalenchuk.samsungtvkeyboard.device;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.util.Log;

import com.kalenchuk.samsungtvkeyboard.exception.ApplicationException;
import com.sec.android.allshare.Device;
import com.sec.android.allshare.Device.DeviceDomain;
import com.sec.android.allshare.Device.DeviceType;
import com.sec.android.allshare.DeviceFinder;
import com.sec.android.allshare.DeviceFinder.IDeviceFinderEventListener;
import com.sec.android.allshare.ERROR;
import com.sec.android.allshare.ServiceConnector;
import com.sec.android.allshare.ServiceConnector.IServiceConnectEventListener;
import com.sec.android.allshare.ServiceConnector.ServiceState;
import com.sec.android.allshare.ServiceProvider;
import com.sec.android.allshare.control.TVController;

public class SamsungTv {
	private static final String TAG = SamsungTv.class.getSimpleName();
	
	private TVController tv;
	private List<Device> availableDevices = new ArrayList<Device>();
	
	private ServiceProvider mServiceProvider = null;

	private final DeviceFinder.IDeviceFinderEventListener mDeviceDiscoveryListener = new IDeviceFinderEventListener() {
		@Override
		public void onDeviceRemoved(DeviceType deviceType, Device device, ERROR err) {
			Log.d(TAG, "TV: " + device.getName() + " [" + device.getIPAddress() + "] is removed." + "\r\n");
		}

		@Override
		public void onDeviceAdded(DeviceType deviceType, Device device, ERROR err) {
			Log.d(TAG, "TV: " + device.getName() + " [" + device.getIPAddress() + "] is found." + "\r\n");
		}
	};
	
	public SamsungTv(Context context) throws ApplicationException {
		createServiceProvider(context);
		
	}

	private void createServiceProvider(Context context) throws ApplicationException {
		ERROR err = ServiceConnector.createServiceProvider(context, new IServiceConnectEventListener() {
			@Override
			public void onCreated(ServiceProvider sprovider, ServiceState state) {
				mServiceProvider = sprovider;
			}

			@Override
			public void onDeleted(ServiceProvider sprovider) {
				mServiceProvider = null;
			}
		});

		processException(err);
	}

	private void processException(ERROR err) throws ApplicationException {
		if (err == ERROR.FRAMEWORK_NOT_INSTALLED) {
			throw new ApplicationException("The AllShare Framework is not installed.");
		} else if (err == ERROR.INVALID_ARGUMENT) {
			throw new ApplicationException("The unexpected error is occurred.");
		} else {
			throw new ApplicationException("The unexpected error is occurred.");
		}
	}
	
	private void findAvailableDevices() {
		if (mServiceProvider == null) {
			Log.d(TAG, "The service provider is not initialized.");
		}
		DeviceFinder mDeviceFinder = mServiceProvider.getDeviceFinder();
		mDeviceFinder.setDeviceFinderEventListener(DeviceType.DEVICE_TV_CONTROLLER, mDeviceDiscoveryListener);
		ArrayList<Device> mDeviceList = mDeviceFinder.getDevices(DeviceDomain.LOCAL_NETWORK, DeviceType.DEVICE_AVPLAYER);
		availableDevices = new ArrayList<Device>();
		availableDevices.addAll(mDeviceList);
	}
	
	private void connect(Device device) {
		if(device != null) {
			tv = (TVController) device;
		}
	}

	private void destroy() {
		if (mServiceProvider != null) {
			ServiceConnector.deleteServiceProvider(mServiceProvider);
		}
		if(tv != null) {
			tv.disconnect();
		}
	}
	
	public void sendText(String text) {
		if(tv == null || availableDevices == null || availableDevices.size() == 0) {
			findAvailableDevices();
			if(availableDevices.size() > 0) {
				connect(availableDevices.get(0));
				ERROR error = tv.sendKeyboardString(text);
				Log.d(TAG, error.name());
			}
		}
	}

	public List<Device> getAvailableDevices() {
		return availableDevices;
	}

	public void setAvailableDevices(List<Device> availableDevices) {
		this.availableDevices = availableDevices;
	}

	public TVController getTv() {
		return tv;
	}

}
